﻿/**
* CRL
*/
using CRL.Core;
using CRL;
using CRL.DBAccess;
using CRL.EventBus.Queue;
using CRL.RabbitMQ;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Text;
using rbmq = RabbitMQ.Client;
namespace CRL.EventBus
{
    public enum MQType
    {
        None,
        RabbitMQ,
        Redis,
        Memory,
        Db,
        RocketMQ
    }
    public class QueueConfig
    {
        internal bool fromNetCoreInjection;
        internal List<ConfigBase> settings = new List<ConfigBase>();
        public ConfigBase GetMqSetting(MQType mqType)
        {
            if (settings.Count == 0)
            {
                throw new Exception("û���κ�����");
            }
            if (settings.Count == 1)
            {
                return settings.First();
            }
            if (mqType == MQType.None)
            {
                return settings.First();
            }
            var find = settings.Find(b => b.MQType == mqType);
            return find ?? settings.First();
        }
        public void AddSetting(ConfigBase config)
        {
            settings.RemoveAll(b => b.MQType == config.MQType);
            settings.Add(config);
        }
        public void UseMemory()
        {
            AddSetting(new ConfigBase
            {
                MQType = MQType.Memory,
                InstanceType = (config, args) =>
                {
                    return new MemoryQueue(config);
                }
            });
        }
        public void UseRabbitMQ(Action<ConnectionConfig> configFunc, Action<ConsumeOption> option = null)
        {
            var confg = new ConnectionConfig();
            configFunc(confg);
            var host = confg.HostName;
            var port = confg.Port;
            var arry = host.Split(':');
            if (arry.Length > 1 && port == 0)
            {
                port = Convert.ToInt32(arry[1]);
            }
            AddSetting(new RabbitMQConfig
            {
                MQType = MQType.RabbitMQ,
                configFunc = configFunc,
                consumeOption = option,
                InstanceType = (config, args) =>
                {
                    return new Queue.RabbitMQ(config,(bool)args);
                }
            });
            
        }
        public void UseRedis(string conn)
        {
            var cb = new ConfigBuilder();
            RedisProvider.Extension.UseRedis(cb, conn);
            AddSetting(new ConfigBase
            {
                ConnString = conn,
                MQType = MQType.Redis,
                InstanceType = (config, args) =>
                {
                    return new Redis(config);
                }
            });
        }
        public void UseDb(Action<DbQueueConfig> configFunc)
        {
            var config = new DbQueueConfig
            {
                MQType = MQType.Db,
                InstanceType = (config2, args) =>
                {
                    return new DbQueue(config2);
                }
            };
            configFunc(config);
            AddSetting(config);
            var builder = DBConfigRegister.GetInstance();
            builder.RegisterDBAccessBuild(dbLocation =>
            {
                if (dbLocation.ManageName == "_eventBusQueue")
                {
                    return new DBAccessBuild(config.DBType, config.ConnString);
                }
                return null;
            });
        }
        /// <summary>
        /// ע�������ط���ʱ�Ƴ��ص�
        /// </summary>
        /// <param name="func"></param>
        public void RegisterOnEventDataRemove(Action<MsgPackage> func)
        {
            SubscribeService._OnEventDataRemove = func;
        }

        internal Assembly[] SubscribeAssemblies = new Assembly[] { };

        /// <summary>
        /// ע�ᶩ�����ڵĳ���
        /// </summary>
        /// <param name="asb"></param>
        public void RegisterSubscribe(params Assembly[] asb)
        {
            SubscribeAssemblies = asb;
        }

        internal string getEventName(string name)
        {
            return name;
        }
    }
    public class ConfigBase
    {
        public Func<ConfigBase,object, AbsQueue> InstanceType { get; set; }
        public MQType MQType { get; set; }
        public string ConnString { get; set; }
        public string GroupName { get; set; }
    }
}
